Fk.map = (function() {
    google.maps.visualRefresh = true;
    var _map,
            _bounds,
            _zoomChanged = false,
            _directionDisplay,
            _latField,
            _lonField,
            _currMarker;

    function _initialize(x, y, zoom, maptype, mapDivId) {
        mapDivId = typeof mapDivId !== 'undefined' ? mapDivId : 'map_canvas';
        maptype = typeof maptype !== 'undefined' ? maptype : google.maps.MapTypeId.ROADMAP;
        zoom = typeof zoom !== 'undefined' ? zoom : 7;

        _map = new google.maps.Map(Fk.$(mapDivId));
        _directionDisplay = new google.maps.DirectionsRenderer();
        _directionDisplay.setMap(_map);

        _bounds = new google.maps.LatLngBounds();
        var myOptions = {
            zoom: zoom,
            mapTypeId: maptype,
            panControl: true,
            zoomControl: true,
            streetViewControl: false,
            mapTypeControl: false

        };
        if ((typeof x !== 'undefined') && (typeof y !== 'undefined')) {
            myOptions.center = new google.maps.LatLng(x, y);
            _bounds.extend(new google.maps.LatLng(x, y));
        }
        _map.setOptions(myOptions);
    }

    function _addMarker(latLng, icon_path, title, animation) {
        new google.maps.Marker({
            position: latLng,
            map: _map,
            title: title,
            animation: animation,
            icon: icon_path
        });
    }

    function _initializeSelectCoordOnMap(latFieldId, LonFieldId) {
        _latField = Fk.$(latFieldId);
        _lonField = Fk.$(LonFieldId);
        _currMarker = new google.maps.Marker({ map: _map });
        if(_latField.value !== '' && _lonField.value !== '')
            _currMarker.setPosition(_map.getCenter());

        google.maps.event.addListener(_map, 'click', function(e) {
                _currMarker.setPosition(e.latLng);
                _latField.value = e.latLng.lat();
                _lonField.value = e.latLng.lng();
        });
    }

    function _displayTravelDest(travelDest) {
        google.maps.event.addListener(_map, 'zoom_changed', function() {
            _zoomChanged = true;
            setTimeout(function() {
                _zoomChanged = false;
            }, 3000);
        });
        var markerCoord = null;
        var c = 0;
        var interval = setInterval(function() {
            markerCoord = new google.maps.LatLng(travelDest[c].lat, travelDest[c].lon);
            _addMarker(markerCoord, null, travelDest[c].place, google.maps.Animation.DROP);
            _bounds.extend(markerCoord);
            if (!_zoomChanged) {
                _map.setCenter(markerCoord);
            }
            c++;
            if (c >= travelDest.length) {
                clearInterval(interval);
                _map.fitBounds(_bounds);
                _map.setZoom(2);
                google.maps.event.clearListeners(_map, 'zoom_changed');
            }
        }, 2000);
    }

    function _displayDirection(from, to) {
        var request = {
            origin: from,
            destination: to,
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        };
        new google.maps.DirectionsService().route(request, function(response, status) {
            if (status === google.maps.DirectionsStatus.OK) {
                _directionDisplay.setDirections(response);
            }
        });
    }

    return{
        init: _initialize,
        add: _addMarker,
        displayTravelDest: _displayTravelDest,
        displayDirection: _displayDirection,
        initSelectCoordOnMap: _initializeSelectCoordOnMap
    };

}());